/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * DlgFace.java
 *
 * Created on 05 22, 11, 4:32:27 PM
 */
package trialinventory2.fce;

import java.awt.event.MouseEvent;
import trialinventory2.to.ListTO;
import com.jgoodies.binding.adapter.AbstractTableAdapter;
import com.jgoodies.binding.adapter.SingleListSelectionAdapter;
import com.jgoodies.binding.list.ArrayListModel;
import com.jgoodies.binding.list.SelectionInList;
import java.awt.Window;
import java.text.MessageFormat;
import java.util.List;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import overallPOS.modules.share.utils.Application;
import overallPOS.modules.share.utils.CloseDialog;
import overallPOS.modules.share.utils.RefreshList;
import overallPOS.modules.share.utils.TableWidthUtilities;
import overallPOS.modules.share.utils.HelpScrollToView;
import trialinventory2.svc.S1;
import trialinventory2.to.ProductTO;

/**
 *
 * @author i1
 */
public class DlgFace extends javax.swing.JDialog {

    //<editor-fold defaultstate="collapsed" desc=" callback ">
    private Callback callback;

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    private ArrayListModel tblList_ALM;
    private TblList_M tblList_M;


    private void init_tblList() {

        tblList_ALM = new ArrayListModel();
        tblList_M = new TblList_M(tblList_ALM);
        tblList.setModel(tblList_M);
        tblList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        tblList.setRowHeight(25);


        TableWidthUtilities.setColumnWidth(tblList, 1, 100);
        TableWidthUtilities.setColumnWidth(tblList, 2, 100);
        TableWidthUtilities.setColumnWidth(tblList, 3, 100);

        TableWidthUtilities.setColumnRightRenderer(tblList, 1);
        TableWidthUtilities.setColumnRightRenderer(tblList, 2);
        TableWidthUtilities.setColumnRightRenderer(tblList, 3);
    }

    private void tbEntry_Change() {
        int idx = tbEntryList.getSelectedIndex();
        if(idx == 1) {

            List<ListTO> lto = S1.getListOfEntry();

            tblList_ALM.clear();
            tblList_ALM.addAll(lto);
            tblList_M.fireTableDataChanged();
            tblList.updateUI();
        }
    }

    private void miList_edit() {
        int row = tblList.getSelectedRow();
        ListTO to = (ListTO) tblList_ALM.get(row);

        Window w = (Window) getSurface().getTopLevelAncestor();
        DlgEdit d = DlgEdit.create(w, true);
        d.setTitle("Edit");
        d.loadListTO(to);
        d.setCallback(new DlgEdit.Callback() {

            public void ok(CloseDialog closeDialog, DlgEdit.Data data) {

                S1.updateListTO(data.to);
                tblList_M.fireTableDataChanged();
                tblList.updateUI();
                closeDialog.ok();
            }
        });

        Application.locateOnParentCenter(w, d);
        d.setVisible(true);

    }




    private static class TblList_M extends AbstractTableAdapter{

        private static final String[] COLUMNS = {
          "Product","Price","Quantity","Total"
        };


        public TblList_M(ListModel listModel) {
          super(listModel,COLUMNS);
        }



        public Object getValueAt(int rowIndex, int columnIndex) {
           ListTO to = (ListTO) getRow(rowIndex);

           switch(columnIndex) {

               case 0:
                   return MessageFormat.format(" {0} ", to.product);

               case 1:
                   return MessageFormat.format(" {0,number,#,##0.00} ", to.price);

               case 2:
                   return MessageFormat.format(" {0,number,#} ", to.getQuantity());

               default:
                   return MessageFormat.format(" {0,number,#,##0.00} ", to.getTotal());

           }



        }
    }


    public static interface Callback {

        void ok(CloseDialog closeDialog, Data data);
    }

    public static class Data {

        public final double qty;
        public final double disc;

        public Data(double qty, double disc) {
            this.qty = qty;
            this.disc = disc;
        }
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" Constructors ">
    private DlgFace(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        myInit();
    }

    private DlgFace(java.awt.Dialog parent, boolean modal) {
        super(parent, modal);
        initComponents();
        myInit();
    }

    public DlgFace() {
        super();
        initComponents();
        myInit();
    }
    private DlgFace myRef;

    private void setThisRef(DlgFace myRef) {
        this.myRef = myRef;
    }
    private static java.util.Map<Object, DlgFace> dialogContainer = new java.util.HashMap();

    public static void clearUpFirst(java.awt.Window parent) {
        if (dialogContainer.containsKey(parent)) {
            dialogContainer.remove(parent);
        }
    }

    public static DlgFace create(java.awt.Window parent, boolean modal) {

        if (modal) {
            return create(parent, ModalityType.APPLICATION_MODAL);
        }

        return create(parent, ModalityType.MODELESS);

    }

    public static DlgFace create(java.awt.Window parent, java.awt.Dialog.ModalityType modalType) {

        if (parent instanceof java.awt.Frame) {

            DlgFace dialog = dialogContainer.get(parent);

            if (dialog == null) {
                dialog = new DlgFace((java.awt.Frame) parent, false);
                dialog.setModalityType(modalType);
                dialogContainer.put(parent, dialog);
                java.util.logging.Logger.getAnonymousLogger().info("instances: " + dialogContainer.size());
                dialog.setThisRef(dialog);
                return dialog;
            } else {
                dialog.setModalityType(modalType);
                return dialog;
            }

        }

        if (parent instanceof java.awt.Dialog) {
            DlgFace dialog = dialogContainer.get(parent);

            if (dialog == null) {
                dialog = new DlgFace((java.awt.Dialog) parent, false);
                dialog.setModalityType(modalType);
                dialogContainer.put(parent, dialog);
                java.util.logging.Logger.getAnonymousLogger().info("instances: " + dialogContainer.size());
                dialog.setThisRef(dialog);
                return dialog;
            } else {
                dialog.setModalityType(modalType);
                return dialog;
            }

        }

        return null;

    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" main ">
    public static void main(String args[]) {

        try {
            javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

//        java.awt.EventQueue.invokeLater(new Runnable() {
//
//            public void run() {
//                try {
        DlgFace dialog = DlgFace.create(new javax.swing.JFrame(), true);
        dialog.setVisible(true);
//                } catch (Exception e) {
//                    throw new RuntimeException(e);
//                } finally {
//                    System.exit(0);
//                }
//            }
//        });
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc=" added ">
    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible == true) {
            getContentPane().removeAll();
            initComponents();
            myInit();
            repaint();
            validateTree();
        }


    }

    public javax.swing.JPanel getSurface() {
        return (javax.swing.JPanel) getContentPane();
    }

    public void nullify() {
        myRef.setVisible(false);
        myRef = null;
    }
    //</editor-fold>

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        pmList = new javax.swing.JPopupMenu();
        miList_edit = new javax.swing.JMenuItem();
        tbEntryList = new javax.swing.JTabbedPane();
        pnlEntry = new javax.swing.JPanel();
        spProducts = new javax.swing.JScrollPane();
        tblProducts = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        tfCashierName = new javax.swing.JTextField();
        dspTotal = new javax.swing.JLabel();
        btnAdd = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        btnSubmit = new javax.swing.JButton();
        pnlList = new javax.swing.JPanel();
        spList = new javax.swing.JScrollPane();
        tblList = new javax.swing.JTable();

        miList_edit.setText("Edit");
        miList_edit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miList_editActionPerformed(evt);
            }
        });
        pmList.add(miList_edit);

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        tbEntryList.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                tbEntryListStateChanged(evt);
            }
        });

        tblProducts.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Product", "Quantity", "Price", "Total"
            }
        ));
        spProducts.setViewportView(tblProducts);

        jLabel1.setText("Cashier Name");

        dspTotal.setBackground(java.awt.Color.white);
        dspTotal.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        dspTotal.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        dspTotal.setOpaque(true);

        btnAdd.setText("Add");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });

        jLabel2.setText("Total");

        btnSubmit.setText("Submit");
        btnSubmit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSubmitActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlEntryLayout = new javax.swing.GroupLayout(pnlEntry);
        pnlEntry.setLayout(pnlEntryLayout);
        pnlEntryLayout.setHorizontalGroup(
            pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 411, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlEntryLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(spProducts, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 387, Short.MAX_VALUE)
                    .addGroup(pnlEntryLayout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(dspTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(btnSubmit, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnlEntryLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(118, 118, 118)
                        .addGroup(pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(tfCashierName, javax.swing.GroupLayout.PREFERRED_SIZE, 172, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(pnlEntryLayout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 75, Short.MAX_VALUE)
                                .addComponent(btnAdd, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap())
        );
        pnlEntryLayout.setVerticalGroup(
            pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlEntryLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(tfCashierName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(12, 12, 12)
                .addComponent(btnAdd)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(spProducts, javax.swing.GroupLayout.DEFAULT_SIZE, 195, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(pnlEntryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(dspTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(22, 22, 22)
                .addComponent(btnSubmit)
                .addContainerGap())
        );

        tbEntryList.addTab("Entry", pnlEntry);

        tblList.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        tblList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                tblListMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                tblListMouseReleased(evt);
            }
        });
        spList.setViewportView(tblList);

        javax.swing.GroupLayout pnlListLayout = new javax.swing.GroupLayout(pnlList);
        pnlList.setLayout(pnlListLayout);
        pnlListLayout.setHorizontalGroup(
            pnlListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlListLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spList, javax.swing.GroupLayout.DEFAULT_SIZE, 371, Short.MAX_VALUE)
                .addGap(28, 28, 28))
        );
        pnlListLayout.setVerticalGroup(
            pnlListLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlListLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(spList, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
                .addContainerGap())
        );

        tbEntryList.addTab("List", pnlList);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tbEntryList, javax.swing.GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tbEntryList, javax.swing.GroupLayout.PREFERRED_SIZE, 425, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
        add();
}//GEN-LAST:event_btnAddActionPerformed

    private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSubmitActionPerformed
        submit();
}//GEN-LAST:event_btnSubmitActionPerformed

    private void tbEntryListStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tbEntryListStateChanged
        tbEntry_Change();
    }//GEN-LAST:event_tbEntryListStateChanged

    private void tblListMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tblListMousePressed
        pmList(evt);
    }//GEN-LAST:event_tblListMousePressed

    private void tblListMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tblListMouseReleased
         pmList(evt);
    }//GEN-LAST:event_tblListMouseReleased

    private void miList_editActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miList_editActionPerformed
        miList_edit();
    }//GEN-LAST:event_miList_editActionPerformed

    private void pmList(MouseEvent evt) {
        if(evt.isPopupTrigger()) {

             pmList.show(evt.getComponent(), evt.getX(), evt.getY());

        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnSubmit;
    private javax.swing.JLabel dspTotal;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JMenuItem miList_edit;
    private javax.swing.JPopupMenu pmList;
    private javax.swing.JPanel pnlEntry;
    private javax.swing.JPanel pnlList;
    private javax.swing.JScrollPane spList;
    private javax.swing.JScrollPane spProducts;
    private javax.swing.JTabbedPane tbEntryList;
    private javax.swing.JTable tblList;
    private javax.swing.JTable tblProducts;
    private javax.swing.JTextField tfCashierName;
    // End of variables declaration//GEN-END:variables

    private void myInit() {
        init_tblProducts();
        init_tblList();
    }



    private void prssAdd_ok(CloseDialog closeDialog, DlgFace_add.Data data) {

        System.out.println(data);
        List<ProductTO> tos = RefreshList.extractList(tblProducts_SIL);
        ProductTO to = new ProductTO(data.product, data.price);
        to.setQuantity(data.quantity);

        int idx = tos.indexOf(to);

        if (idx > -1) {
            ProductTO oldTO = tos.remove(idx);
            oldTO.setQuantity(oldTO.getQuantity() + to.getQuantity());
            tos.add(idx, oldTO);
        } else {
            tos.add(to);
        }

        tblProducts_M.fireTableDataChanged();


        int sel = tos.indexOf(to);
        tblProducts.setRowSelectionInterval(sel, sel);
        HelpScrollToView.view(sel, tblProducts, spProducts);


        tblProducts.updateUI();
        closeDialog.ok();
    }

    private void add() {
        //todo call add dialog
        Window p = (Window) getSurface().getTopLevelAncestor();
        DlgFace_add d = DlgFace_add.create(p, true);
        d.setCallback(new DlgFace_add.Callback() {

            public void ok(CloseDialog closeDialog, DlgFace_add.Data data) {
                prssAdd_ok(closeDialog, data);
            }
        });

        Application.locateOnParentCenter(p, d);
        d.setVisible(true);
    }

    private void submit() {
        
        List<ProductTO> save = RefreshList.extractList(tblProducts_SIL);
        String who = tfCashierName.getText();
        S1.save(save, who);


        save.clear();
        tblProducts_M.fireTableDataChanged();
        tblProducts.updateUI();
    }


    private void compute() {
        List<ProductTO> tos = RefreshList.extractList(tblProducts_SIL);

        double total = 0;
        for (ProductTO to : tos) {
            total += to.getTotal();
        }

        dspTotal.setText(total + "");
        System.out.println(total + "");

    }
    private TblProducts_M tblProducts_M;
    private SelectionInList tblProducts_SIL;

    private void init_tblProducts() {
        tblProducts_SIL = new SelectionInList();
        tblProducts_M = new TblProducts_M(tblProducts_SIL);
        tblProducts_M.addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent e) {
                compute();
            }
        });

        tblProducts.setModel(tblProducts_M);
        tblProducts.setSelectionModel(new SingleListSelectionAdapter(
                tblProducts_SIL.getSelectionHolder()));
        tblProducts.setRowHeight(25);

        TableWidthUtilities.setColumnWidth(tblProducts, 1, 100);
        TableWidthUtilities.setColumnWidth(tblProducts, 2, 100);
        TableWidthUtilities.setColumnWidth(tblProducts, 3, 100);

        TableWidthUtilities.setColumnRightRenderer(tblProducts, 1);
        TableWidthUtilities.setColumnRightRenderer(tblProducts, 2);
        TableWidthUtilities.setColumnRightRenderer(tblProducts, 3);
    }

    private static class TblProducts_M extends AbstractTableAdapter {

        private static final String[] COLUMNS = {
            "Product", "Price", "Quantity", "Total"
        };

        public TblProducts_M(ListModel listModel) {
            super(listModel, COLUMNS);
        }

        public Object getValueAt(int row, int col) {
            ProductTO to = (ProductTO) getRow(row);

            switch (col) {
                case 0:
                    return to.product;
                case 1:
                    return to.price;
                case 2:
                    return to.getQuantity();
                default:
                    return to.getTotal();
            }
        }
    }
}
